#include "AppLayer.h"
#include "AppSence.h"
#include <time.h>
#include "platform.h"
#include "AppDefine.h"
#include "MySprite.h"
using namespace cocos2d;

static int begCol,begRow = -1;
static float begX,begY = 0;

MySprite *spriteSets[TOT_ROW_NUM][TOT_COL_NUM]={NULL};

AppLayer::AppLayer()
{
	setIsTouchEnabled( true );

	CCSpriteBatchNode *spriteBatch=CCSpriteBatchNode::batchNodeWithFile("a.png");  
	this->addChild(spriteBatch);  
	CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("a.plist"); 
    
	//GL的原点在屏幕左下角 图片的排列也是 从下到上 从左到右

	for(int row_num = 0; row_num < TOT_ROW_NUM; row_num++){
		for(int col_num =0; col_num<TOT_COL_NUM; col_num++){
			
			float center_x = (0.5 + col_num)*cell_width*scale;
			float center_y =(0.5+row_num)*cell_height*scale;

			int index = CCRANDOM_0_1()*6+1;
			char frameName[10]={'\0'};
			MySprite *pSprite=(MySprite*)MySprite::spriteWithSpriteFrameName(getFrameNameByIndex(index,frameName));
			pSprite->initActionArray();
			pSprite->setScale(scale);
			pSprite->setData(index);
			pSprite->setPosition(ccp(center_x, center_y) );
			
			this->addChild(pSprite, 0);
			spriteSets[row_num][col_num]=pSprite;
			
		}
	}

	checkAndProcess();
}

void AppLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
	CCLog("ccTouchesBegan");
	CCSetIterator it = pTouches->begin();
    CCTouch* touch = (CCTouch*)(*it);
    CCPoint touchLocation = touch->locationInView( touch->view() );	
    touchLocation = CCDirector::sharedDirector()->convertToGL( touchLocation );
	
	begX = touchLocation.x;
	begY = touchLocation.y;
	int curCol = ((int)(touchLocation.x))/((int)(cell_width*scale));
	int curRow = ((int)(touchLocation.y))/((int)(cell_height*scale)); 

	if(curCol<TOT_COL_NUM && curRow<TOT_ROW_NUM){
		begCol = curCol;
		begRow = curRow;
	}else{
		resetBegXY();
	}
}

void AppLayer::ccTouchesEnded(CCSet* pTouches, CCEvent* event)
{
	CCLog("ccTouchesEnded");
	CCSetIterator it = pTouches->begin();
    CCTouch* touch = (CCTouch*)(*it);
    CCPoint touchLocation = touch->locationInView( touch->view() );	
    touchLocation = CCDirector::sharedDirector()->convertToGL( touchLocation );
	

	int curCol = begCol;
	int curRow = begRow;

	if(abs(touchLocation.x -begX) >= abs(touchLocation.y -begY)){

		if(touchLocation.x -begX > 0){
		curCol =begCol + 1;
		}else if(touchLocation.x -begX < 0){
			curCol =begCol - 1;
		}
	}else{
		if(touchLocation.y -begY > 0){
		curRow =begRow + 1;
		}else if(touchLocation.y -begY < 0){
			curRow =begRow - 1;
		}
	}
	
	
	//CCLog("begCol=%d begRow=%d",begCol,begRow);
	//CCLog("curCol=%d curRow=%d",curCol,curRow);
	/*int curCol = ((int)(touchLocation.x))/((int)(cell_width*scale));
	int curRow = ((int)(touchLocation.y))/((int)(cell_height*scale)); */

	if(curCol>-1 && curCol<TOT_COL_NUM && curRow>-1 && curRow<TOT_ROW_NUM){
		if(begCol>-1 && begRow>-1 && (curCol!=begCol || curRow!=begRow) && abs(curCol-begCol)+abs(curRow-begRow)==1 ){
			
			swapSprite(begRow,begCol,curRow,curCol);
			checkAndProcess();
		}
	}
	resetBegXY();

}
void AppLayer::checkAndProcess()
{
	while(markAllLink())
	{
		blankAllLink();  //重置被标记的精灵
		checkAllBlank(); //将被重置的精灵移动到最顶端
		fallDownAllSprite(); //将被重置的精灵随机恢复
	}
}
void AppLayer::fallDownAllSprite()
{
	for(int i=0; i<TOT_ROW_NUM; i++){
		for(int j=0; j<TOT_COL_NUM; j++){

			if(spriteSets[i][j]->getData() == -1)
			{
				int index = CCRANDOM_0_1()*6+1;
				spriteSets[i][j]->setData(index);
				spriteSets[i][j]->setMarked(false);

				spriteSets[i][j]->setPosition(CCPointMake((j+0.5)*cell_width*scale,800));

				char frameName[10]={'\0'};
				CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(getFrameNameByIndex(index,frameName));
				spriteSets[i][j]->setDisplayFrame(frame); 
				reRenderSprite(i,j);
			}

		}
	}

}

void AppLayer::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){
	CCLog("ccTouchesMoved");
}

void AppLayer::resetBegXY()
{
	begX = 0;
	begY = 0;
	begCol = -1;
	begRow = -1;
}

void AppLayer::swapSprite(int begRow,int begCol, int curRow, int curCol)
{

	MySprite *pSpriteA = spriteSets[begRow][begCol];
	MySprite *pSpriteB = spriteSets[curRow][curCol];

	spriteSets[begRow][begCol] = pSpriteB;
	spriteSets[curRow][curCol] = pSpriteA;
	
	reRenderSprite(begRow,begCol);
	reRenderSprite(curRow,curCol);
}

long AppLayer::millisecondNow()  
{ 
	struct cocos2d::cc_timeval now;
    cocos2d::CCTime::gettimeofdayCocos2d(&now, NULL);    
    return (now.tv_sec * 1000 + now.tv_usec /1000.0);
}

void AppLayer::markSprite(int row,int col)
{
	spriteSets[row][col]->setMarked(true);
}

bool AppLayer::hasNoBlankSprite(int row, int col)
{
	for(int i=row+1; i<TOT_ROW_NUM; i++){
		if(spriteSets[i][col]->getData() != -1){
			return true;
		}
	}
	return false;
}

void AppLayer::reRenderSprite(int row,int col,ccTime delyTime)
{
	CCActionInterval*  actionTo = CCMoveTo::actionWithDuration(delyTime, CCPointMake((col+0.5)*cell_width*scale,(row+0.5)*cell_height*scale));
	spriteSets[row][col]->runAction(actionTo);
}

void AppLayer::addAction(int row,int col,ccTime delyTime)
{
	CCActionInterval*  actionTo = CCMoveTo::actionWithDuration(delyTime, CCPointMake((col+0.5)*cell_width*scale,(row+0.5)*cell_height*scale));
	spriteSets[row][col]->addAction(actionTo);
}

bool AppLayer::moveDownAllSprite(int row, int col)
{
	MySprite *me = spriteSets[row][col];
	for(int i=row; i<TOT_ROW_NUM-1; i++){
		spriteSets[i][col] = spriteSets[i+1][col];
	}
	spriteSets[TOT_ROW_NUM-1][col] = me;

	for(int i=row; i<TOT_ROW_NUM; i++){
		reRenderSprite(i,col);
	}

	return false;
}

bool AppLayer::checkAllBlank()
{
	for(int j=0; j<TOT_COL_NUM; j++){
		for(int i=0; i<TOT_ROW_NUM; i++){
			int data=spriteSets[i][j]->getData();
			while(data == -1 && hasNoBlankSprite(i,j)){
				
				//从本Sprite开始，本列上方的Sprite逐一下落一行 本Sprite移到最顶端
				moveDownAllSprite(i, j);
				data = spriteSets[i][j]->getData();
			}
		}
	}
	
	return true;
}

void AppLayer::blankAllLink()
{
	CCSpriteFrame *frame=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName("0.png");  
	
	for(int j=0; j<TOT_COL_NUM; j++){
		for(int i=0; i<TOT_ROW_NUM; i++){
			if(spriteSets[i][j]->getMarked() == true)
			{
				spriteSets[i][j]->setData(-1);
				spriteSets[i][j]->setDisplayFrame(frame); 
				//CCActionInterval*  actionRot = CCRotateBy::actionWithDuration(0.5,360);
				//spriteSets[i][j]->addAction(actionRot);
				//addAction(i,j);
				//spriteSets[i][j]->runMyActions();

			}
		}
	}


	

}

bool AppLayer::markAllLink()
{
	bool hasLink = false; //是否有连

	//逐行判断
	for(int i=0; i<TOT_ROW_NUM; i++){
		for(int j=0; j<=TOT_COL_NUM-3; j++){
			int data1=spriteSets[i][j]->getData();
			int data2=spriteSets[i][j+1]->getData();
			int data3=spriteSets[i][j+2]->getData();
			if(data1!=-1 && data1==data2 && data1==data3)
			{
				CCLog("--start [x,y]=[%d,%d]---",i,j);
				markSprite(i,j);
				markSprite(i,j+1);
				markSprite(i,j+2);
				hasLink = true;
			}
		}
	}

	//逐列判断
	for(int j=0; j<TOT_COL_NUM; j++){
		for(int i=0; i<=TOT_ROW_NUM-3; i++){
			int data1=spriteSets[i][j]->getData();
			int data2=spriteSets[i+1][j]->getData();
			int data3=spriteSets[i+2][j]->getData();
			if(data1!=-1&&data1==data2 && data1==data3)
			{
				CCLog("--start [x,y]=[%d,%d]---",i,j);
				markSprite(i,j);
				markSprite(i+1,j);
				markSprite(i+2,j);
				hasLink = true;
			}
		}
	}
	
	return hasLink;
}


char* AppLayer::getFrameNameByIndex(int index,char* frameName)
{
	sprintf(frameName,"%d.png",index);
	return frameName;
}



